home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2005 October / PCWOCT05.iso / Software / FromTheMag / XAMPP 1.4.14 / xampp-win32-1.4.14-installer.exe / xampp / php / pear / Auth / PrefManager.php < prev    next >
PHP Script  |  2004-10-01  |  16KB  |  416 lines

  1. <?php
  2. require_once("DB.php");
  3.  
  4. /**
  5.  * A simple preference manager, takes userid, preference name pairs and returns the value
  6.  * of that preference.
  7.  *  
  8.  * CREATE TABLE `preferences` (
  9.  * `user_id` varchar( 255 ) NOT NULL default '',
  10.  * `pref_id` varchar( 32 ) NOT NULL default '',
  11.  * `pref_value` longtext NOT NULL ,
  12.  *     PRIMARY KEY ( `user_id` , `pref_id` )
  13.  * )
  14.  * 
  15.  * @author Jon Wood <jon@jellybob.co.uk>
  16.  * @package Auth_PrefManager
  17.  * @category Authentication
  18.  */
  19. class Auth_PrefManager
  20. {
  21.     /**
  22.      * The database object.
  23.      * @var object
  24.      * @access private
  25.      */
  26.     var $_db;
  27.  
  28.     /**
  29.      * The user name to get preferences from if the user specified doesn't
  30.      * have that preference set.
  31.      * @var string
  32.      * @access private
  33.      */
  34.     var $_defaultUser = "__default__";
  35.  
  36.     /**
  37.      * Should we search for default values, or just fail when we find out that
  38.      * the specified user didn't have it set.
  39.      * 
  40.      * @var bool
  41.      * @access private
  42.      */
  43.     var $_returnDefaults = true;
  44.  
  45.     /**
  46.      * The table containing the preferences.
  47.      * @var string
  48.      * @access private
  49.      */
  50.     var $_table = "preferences";
  51.  
  52.     /**
  53.      * The column containing user ids.
  54.      * @var string
  55.      * @access private
  56.      */
  57.     var $_userColumn = "user_id";
  58.  
  59.     /**
  60.      * The column containing preference names.
  61.      * @var string
  62.      * @access private
  63.      */
  64.     var $_nameColumn = "pref_id";
  65.  
  66.     /**
  67.      * The column containing preference values.
  68.      * @var string
  69.      * @access private
  70.      */
  71.     var $_valueColumn = "pref_value";
  72.  
  73.     /**
  74.      * The session variable that the cache array is stored in.
  75.      * @var string
  76.      * @access private
  77.      */
  78.      var $_cacheName = "prefCache";
  79.  
  80.     /**
  81.      * The last error given.
  82.      * @var string
  83.      * @access private
  84.      */
  85.     var $_lastError;
  86.  
  87.     /**
  88.      * Defines whether the cache should be used or not.
  89.      * @var bool
  90.      * @access private
  91.      */
  92.     var $_useCache = true;
  93.     
  94.     /**
  95.      * Defines whether values should be serialized before saving.
  96.      * @var bool
  97.      * @access private
  98.      */
  99.     var $_serialize = false;
  100.     
  101.     /**
  102.      * Constructor
  103.      * 
  104.      * Options:
  105.      *  table: The table to get prefs from. [preferences]
  106.      *  userColumn: The field name to search for userid's [user_id]
  107.      *  nameColumn: The field name to search for preference names [pref_name]
  108.      *  valueColumn: The field name to search for preference values [pref_value]
  109.      *  defaultUser: The userid assigned to default values [__default__]
  110.      *  cacheName: The name of cache in the session variable ($_SESSION[cacheName]) [prefsCache]
  111.      *  useCache: Whether or not values should be cached.
  112.      *  serialize: Should preference values be serialzed before saving?
  113.      *
  114.      * @param string $dsn The DSN of the database connection to make, or a DB object.
  115.      * @param array $properties An array of properties to set.
  116.      * @param string $defaultUser The default user to manage for.
  117.      * @return bool Success or failure.
  118.      * @access public
  119.      */
  120.     function Auth_PrefManager($dsn, $properties = NULL)
  121.     {
  122.         // Connect to the database.
  123.         if (isset($dsn)) {
  124.             if (is_subclass_of($dsn, 'db_common')) {
  125.                 $this->_db = &$dsn;
  126.             } else {
  127.                 $this->_db = DB::Connect($dsn);
  128.                 if (DB::isError($this->_db)) {
  129.                     $this->_lastError = "DB Error: ".$this->_db->getMessage();
  130.                 }
  131.             }
  132.         } else {
  133.             $this->_lastError = "No DSN specified.";
  134.             return false;
  135.         }
  136.  
  137.         if (is_array($properties)) {
  138.             if (isset($properties["table"]))        { $this->_table = $this->_db->quoteIdentifier($properties["table"]); }
  139.             if (isset($properties["userColumn"]))   { $this->_userColumn = $this->_db->quoteIdentifier($properties["userColumn"]); }
  140.             if (isset($properties["nameColumn"]))   { $this->_nameColumn = $this->_db->quoteIdentifier($properties["nameColumn"]); }
  141.             if (isset($properties["valueColumn"]))  { $this->_valueColumn = $this->_db->quoteIdentifier($properties["valueColumn"]); }
  142.             if (isset($properties["defaultUser"]))  { $this->_defaultUser = $properties["defaultUser"]; }
  143.             if (isset($properties["cacheName"]))    { $this->_cacheName = $properties["cacheName"]; }
  144.             if (isset($properties["useCache"]))     { $this->_useCache = $properties["useCache"]; }
  145.             if (isset($properties["serialize"]))    { $this->_serialize = $properties["serialize"]; }
  146.         }
  147.  
  148.         return true;
  149.     }
  150.  
  151.     function setReturnDefaults($returnDefaults = true)
  152.     {
  153.         if (is_bool($returnDefaults)) {
  154.             $this->_returnDefaults = $returnDefaults;
  155.         }
  156.     }
  157.  
  158.     /**
  159.      * Sets whether the cache should be used.
  160.      * 
  161.      * @param bool $use Should the cache be used.
  162.      * @access public
  163.      */
  164.     function useCache($use = true)
  165.     {
  166.         $this->_useCache = $use;
  167.     }
  168.     
  169.     /**
  170.      * Cleans out the cache.
  171.      * 
  172.      * @access public
  173.      */
  174.     function clearCache()
  175.     {
  176.         unset($_SESSION[$this->_cacheName]);
  177.     }
  178.  
  179.     /**
  180.      * Get a preference for the specified user, or, if returning default values
  181.      * is enabled, the default.
  182.      * 
  183.      * @param string $user_id The user to get the preference for.
  184.      * @param string $pref_id The preference to get.
  185.      * @param bool $showDefaults Should default values be searched (overrides the global setting).
  186.      * @return mixed The value if it's found, or NULL if it isn't.
  187.      * @access public
  188.      */
  189.     function getPref($user_id, $pref_id, $showDefaults = true)
  190.     {
  191.         if (isset($_SESSION[$this->_cacheName][$user_id][$pref_id]) && $this->_useCache) {
  192.             // Value is cached for the specified user, so give them the cached copy.
  193.             return $_SESSION[$this->_cacheName][$user_id][$pref_id];
  194.         } else {
  195.             // Not cached, search the database for this user's preference.
  196.             $query = sprintf("SELECT * FROM %s WHERE %s=%s AND %s=%s", $this->_table,
  197.                                                                    $this->_userColumn,
  198.                                                                        $this->_db->quote($user_id),
  199.                                                                        $this->_nameColumn,
  200.                                                                        $this->_db->quote($pref_id));
  201.             $result = $this->_db->query($query);
  202.             if (DB::isError($result)) {
  203.                 // Ouch! The query failed!
  204.                 $this->_lastError = "DB Error: ".$result->getMessage();
  205.                 return NULL;
  206.             } else if ($result->numRows()) {
  207.                 // The query found a value, so we can cache that, and then return it.
  208.                 $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
  209.                 $_SESSION[$this->_cacheName][$user_id][$pref_id] = $this->_unpack($row[$this->_valueColumn]);
  210.                 return $_SESSION[$this->_cacheName][$user_id][$pref_id];
  211.             } else if ($this->_returnDefaults && $showDefaults) {
  212.                 // I was doing this with a call to getPref again, but it threw things into an
  213.                 // infinite loop if the default value didn't exist. If you can fix that, it would
  214.                 // be great ;)
  215.                 if (isset($_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id]) && $this->_useCache) {
  216.                     $_SESSION[$this->_cacheName][$user_id][$pref_id] = $_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id];
  217.                     return $_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id];
  218.                 } else {
  219.                     $query = sprintf("SELECT * FROM %s WHERE %s=%s AND %s=%s", $this->_table,
  220.                                                                                $this->_userColumn,
  221.                                                                                $this->_db->quote($this->_defaultUser),
  222.                                                                                $this->_nameColumn,
  223.                                                                                $this->_db->quote($pref_id));
  224.                     $result = $this->_db->query($query);
  225.                     if (DB::isError($result)) {
  226.                         $this->_lastError = "DB Error: ".$result->getMessage();
  227.                         return NULL;
  228.                     } else {
  229.                         if ($result->numRows()) {
  230.                             $row = $result->fetchRow(DB_FETCHMODE_ASSOC);
  231.                             $_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id] = $this->_unpack($row[$this->_valueColumn]);
  232.                             $_SESSION[$this->_cacheName][$user_id][$pref_id] = $_SESSION[$this->_cacheName][$this->_defaultUser][$pref_id];
  233.                             return $_SESSION[$this->_cacheName][$user_id][$pref_id];
  234.                         } else {
  235.                             return NULL;
  236.                         }
  237.                     }
  238.                 }
  239.             } else {
  240.                 // We've used up all the resources we're allowed to search, so return a NULL.
  241.                 return NULL;
  242.             }
  243.         }
  244.     }
  245.  
  246.     /**
  247.     * A shortcut function for getPref($this->_defaultUser, $pref_id, $value),
  248.     * useful if you have a logged in user, but want to get defaults anyway.
  249.     *
  250.     * @param string $pref_id The name of the preference to get.
  251.     * @return mixed The value if it's found, or NULL if it isn't.
  252.     * @access public
  253.     */
  254.     function getDefaultPref($pref_id)
  255.     {
  256.         return $this->getPref($this->_defaultUser, $pref_id);
  257.     }
  258.  
  259.     /**
  260.      * Set a preference for the specified user.
  261.      * 
  262.      * @param string $user_id The user to set for.
  263.      * @param string $pref_id The preference to set.
  264.      * @param mixed $value The value it should be set to.
  265.      * @return bool Sucess or failure.
  266.      * @access public
  267.      */
  268.     function setPref($user_id, $pref_id, $value)
  269.     {
  270.         // Start off by checking if the preference is already set (if it is we need to do
  271.         // an UPDATE, if not, it's an INSERT.
  272.         if ($this->_exists($user_id, $pref_id, false)) {
  273.             $query = sprintf("UPDATE %s SET %s=%s WHERE %s=%s AND %s=%s", $this->_table,
  274.                                                                           $this->_valueColumn,
  275.                                                                           $this->_db->quote($this->_pack($value)),
  276.                                                                           $this->_userColumn,
  277.                                                                           $this->_db->quote($user_id),
  278.                                                                           $this->_nameColumn,
  279.                                                                           $this->_db->quote($pref_id));
  280.         } else {
  281.             $query = sprintf("INSERT INTO %s (%s, %s, %s) VALUES(%s, %s, %s)", $this->_table,
  282.                                                                                $this->_userColumn,
  283.                                                                                $this->_nameColumn,
  284.                                                                                $this->_valueColumn,
  285.                                                                                $this->_db->quote($user_id),
  286.                                                                                $this->_db->quote($pref_id),
  287.                                                                                $this->_db->quote($this->_pack($value)));
  288.         }
  289.         $result = $this->_db->query($query);
  290.         if (DB::isError($result)) {
  291.             $this->_lastError = "DB Error: ".$result->getMessage();
  292.             return false;
  293.         } else {
  294.         if ($this->_useCache) {
  295.             $_SESSION[$this->_cacheName][$user_id][$pref_id] = $value;
  296.         }
  297.             return true;
  298.         }
  299.     }
  300.  
  301.     /**
  302.     * A shortcut function for setPref($this->_defaultUser, $pref_id, $value)
  303.     *
  304.     * @param string $pref_id The name of the preference to set.
  305.     * @param mixed $value The value to set it to.
  306.     * @return bool Sucess or failure.
  307.     * @access public
  308.     */
  309.     function setDefaultPref($pref_id, $value)
  310.     {
  311.         return $this->setPref($this->_defaultUser, $pref_id, $value);
  312.     }
  313.  
  314.     /**
  315.     * Deletes a preference for the specified user.
  316.     * 
  317.     * @param string $user_id The userid of the user to delete from.
  318.     * @param string $pref_id The preference to delete.
  319.     * @return bool Success/Failure
  320.     * @access public
  321.     */
  322.     function deletePref($user_id, $pref_id)
  323.     {
  324.         if ($this->getPref($user_id, $pref_id) == NULL) {
  325.             // The user doesn't have this variable anyway ;)
  326.             return true;
  327.         } else {
  328.             $query = sprintf("DELETE FROM %s WHERE %s=%s AND %s=%s", $this->_table,
  329.                                                                      $this->_userColumn,
  330.                                                                      $this->_db->quote($user_id),
  331.                                                                      $this->_nameColumn,
  332.                                                                      $this->_db->quote($pref_id));
  333.             $result = $this->_db->query($query);
  334.             if (DB::isError($result)) {
  335.                 $this->_lastError = "DB Error: ".$result->getMessage();
  336.                 return false;
  337.             } else {
  338.                 if ($this->_useCache) {
  339.                     unset($_SESSION[$this->_cacheName][$user_id][$pref_id]);
  340.                 }
  341.                 return true;
  342.             }
  343.         }
  344.     }
  345.  
  346.     /**
  347.     * Deletes a preference for the default user.
  348.     * 
  349.     * @param string $pref_id The preference to delete.
  350.     * @return bool Success/Failure
  351.     * @access public
  352.     */
  353.     function deleteDefaultPref($pref_id)
  354.     {
  355.         $this->deletePref($this->_defaultUser, $pref_id);
  356.     }
  357.     
  358.     /**
  359.      * Checks if a preference exists in the database.  
  360.      *
  361.      * @param string $user_id The userid of the preference owner.
  362.      * @param string $pref_id The preference to check for.
  363.      * @return bool True if the preference exists.
  364.      * @access private
  365.      */
  366.     function _exists($user_id, $pref_id)
  367.     {
  368.         $query = sprintf("SELECT COUNT(%s) FROM %s WHERE %s=%s AND %s=%s", $this->_nameColumn,
  369.                                                                            $this->_table,
  370.                                                                            $this->_userColumn,
  371.                                                                            $this->_db->quoteSmart($user_id),
  372.                                                                            $this->_nameColumn,
  373.                                                                            $this->_db->quote($pref_id));
  374.         $result = $this->_db->getOne($query);
  375.         if (DB::isError($result)) {
  376.             $this->_lastError = "DB Error: ".$result->getMessage();
  377.             return false;
  378.         } else {
  379.             return (bool)$result;
  380.         }
  381.     }
  382.  
  383.     /**
  384.      * Does anything needed to prepare a value for saving in the database.
  385.      *
  386.      * @param mixed $value The value to be saved.
  387.      * @return string The value in a format valid for saving to the database.
  388.      * @access private
  389.      */
  390.     function _pack($value)
  391.     {
  392.         if ($this->_serialize) {
  393.             return serialize($value);
  394.         } else {
  395.             return $value;
  396.         }
  397.     }
  398.     
  399.     /**
  400.      * Does anything needed to create a value of the preference, such as unserializing.
  401.      *
  402.      * @param string $value The value of the preference.
  403.      * @return mixed The unpacked version of the preference.
  404.      * @access private
  405.      */
  406.     function _unpack($value)
  407.     {
  408.         if ($this->_serialize) {
  409.             return unserialize($value);
  410.         } else {
  411.             return $value;
  412.         }
  413.     }
  414. }
  415. ?>
  416.